/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.flexbox.test

import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.test.InstrumentationRegistry
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.ViewAction
import androidx.test.espresso.action.*
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.filters.FlakyTest
import androidx.test.filters.MediumTest
import androidx.test.rule.ActivityTestRule
import androidx.test.runner.AndroidJUnit4
import com.google.android.flexbox.*
import com.google.android.flexbox.FlexboxItemDecoration.HORIZONTAL
import com.google.android.flexbox.FlexboxItemDecoration.VERTICAL
import com.google.android.flexbox.test.IsEqualAllowingError.Companion.isEqualAllowingError
import org.hamcrest.Matchers.*
import org.hamcrest.core.IsNot.not
import org.junit.Assert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * Integration tests for [FlexboxLayoutManager].
 */
@RunWith(AndroidJUnit4::class)
@MediumTest
class FlexboxLayoutManagerTest {

    @JvmField
    @Rule
    var activityRule = ActivityTestRule(FlexboxTestActivity::class.java)

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testLoadFromXml() {
        val activity = activityRule.activity
        activityRule.runOnUiThread { activity.setContentView(R.layout.recyclerview_reverse) }
        val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
        val layoutManager = recyclerView.layoutManager
        assertThat(recyclerView, `is`(notNullValue()))
        assertThat(layoutManager, `is`(instanceOf<Any>(FlexboxLayoutManager::class.java)))
        val flexboxLayoutManager = layoutManager as FlexboxLayoutManager
        assertThat(flexboxLayoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(flexboxLayoutManager.flexWrap, `is`(FlexWrap.WRAP))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testChangeAttributesFromCode() {
        val activity = activityRule.activity
        activityRule.runOnUiThread { activity.setContentView(R.layout.recyclerview_reverse) }
        val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
        val layoutManager = recyclerView.layoutManager
        assertThat(recyclerView, `is`(notNullValue()))
        assertThat(layoutManager, `is`(instanceOf<Any>(FlexboxLayoutManager::class.java)))
        val flexboxLayoutManager = layoutManager as FlexboxLayoutManager
        assertThat(flexboxLayoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(flexboxLayoutManager.flexWrap, `is`(FlexWrap.WRAP))

        flexboxLayoutManager.flexDirection = FlexDirection.COLUMN
        flexboxLayoutManager.flexWrap = FlexWrap.NOWRAP
        flexboxLayoutManager.justifyContent = JustifyContent.CENTER
        flexboxLayoutManager.alignItems = AlignItems.FLEX_END
        assertThat(flexboxLayoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(flexboxLayoutManager.flexWrap, `is`(FlexWrap.NOWRAP))
        assertThat(flexboxLayoutManager.justifyContent, `is`(JustifyContent.CENTER))
        assertThat(flexboxLayoutManager.alignItems, `is`(AlignItems.FLEX_END))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_row_not_wrapped() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 120, 80))
            adapter.addItem(createLayoutParams(activity, 120, 80))
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.flexWrap, `is`(FlexWrap.WRAP))
        // Only 2 items are added and all items should be attached (visible). So both
        // getChildCount and getFlexItemCount(including detached items) should return the same value
        assertThat(layoutManager.flexItemCount, `is`(2))
        assertThat(layoutManager.childCount, `is`(2))
        assertThat(layoutManager.flexLines.size, `is`(1))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_row_wrapped() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 120, 80))
            adapter.addItem(createLayoutParams(activity, 120, 80))
            adapter.addItem(createLayoutParams(activity, 120, 80))
            adapter.addItem(createLayoutParams(activity, 120, 80))
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // 4 items are added and all items should be attached (visible). So both
        // getChildCount and getFlexItemCount(including detached items) should return the same value
        assertThat(layoutManager.flexItemCount, `is`(4))
        assertThat(layoutManager.childCount, `is`(4))
        assertThat(layoutManager.flexLines.size, `is`(2))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_row_partOfItems_detached() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            // RecyclerView width: 320, height: 240.
            // Computed FlexContainer width: 320, height: 450
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // In total 9 items are added but the seventh item and the items follow aren't attached
        // (invisible) so are not included in the count of of the getChildCount.
        assertThat(layoutManager.flexItemCount, `is`(9))
        assertThat(layoutManager.childCount, `is`(6))

        // At first only the visible area of the flex lines are calculated
        assertThat(layoutManager.flexLines.size, `is`(3))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_row_scrollVertically() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            adapter.addItem(createLayoutParams(activity, 150, 90))
            // RecyclerView width: 320, height: 240.
            // Computed FlexContainer width: 320, height: 450
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // In total 9 items are added but the seventh item and the items follow aren't attached
        // (invisible) so are not included in the count of of the getChildCount.
        assertThat(layoutManager.flexItemCount, `is`(9))
        assertThat(layoutManager.childCount, `is`(6))
        // At first only the visible area of the flex lines are calculated
        assertThat(layoutManager.flexLines.size, `is`(3))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        assertThat(layoutManager.flexItemCount, `is`(9))
        // The RecyclerView is swiped to top until it reaches the bottom of the view.
        // The number of the visible views should be 5
        assertThat(layoutManager.childCount, `is`(5))
        // Since the RecyclerView is swiped to the bottom, all flex lines should be calculated
        // by now
        assertThat(layoutManager.flexLines.size, `is`(5))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFlexGrow() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 150, 130)
            lp1.flexGrow = 1.0f
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 150, 130)
            lp2.flexGrow = 1.0f
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 150, 130)
            lp3.flexGrow = 1.0f
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // The flexGrow parameters for all LayoutParams are set to 1.0, expecting each child to
        // fill the horizontal remaining space
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(2))
        assertThat(layoutManager.getChildAt(0)!!.width, isEqualAllowingError(activity.dpToPixel(160)))
        assertThat(layoutManager.getChildAt(1)!!.width, isEqualAllowingError(activity.dpToPixel(160)))
        assertThat(layoutManager.getChildAt(2)!!.width, isEqualAllowingError(activity.dpToPixel(320)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_column_partOfItems_detached() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))

            layoutManager.flexDirection = FlexDirection.COLUMN
            // RecyclerView width: 320, height: 240.
            // Computed FlexContainer width: 450, height: 240
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // In total 9 items are added but the seventh item and the items after aren't attached
        // (invisible) so are not included in the count of of the getChildCount.
        assertThat(layoutManager.flexItemCount, `is`(9))
        assertThat(layoutManager.childCount, `is`(6))

        // At first only the visible area of the flex lines are calculated
        assertThat(layoutManager.flexLines.size, `is`(3))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAddViewHolders_direction_column_scrollHorizontally() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))
            adapter.addItem(createLayoutParams(activity, 120, 100))

            layoutManager.flexDirection = FlexDirection.COLUMN
            // RecyclerView width: 320, height: 240.
            // Computed FlexContainer width: 500, height: 240
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // In total 9 items are added but the seventh item and the items follow aren't attached
        // (invisible) so are not included in the count of of the getChildCount.
        assertThat(layoutManager.flexItemCount, `is`(9))
        assertThat(layoutManager.childCount, `is`(6))
        // At first only the visible area of the flex lines are calculated
        assertThat(layoutManager.flexLines.size, `is`(3))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        assertThat(layoutManager.flexItemCount, `is`(9))
        // The RecyclerView is swiped to top until it reaches the right edge of the view.
        // The number of the visible views should be 5
        assertThat(layoutManager.childCount, `is`(5))
        // Since the RecyclerView is swiped to the bottom, all flex lines should be calculated
        // by now
        assertThat(layoutManager.flexLines.size, `is`(5))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexStart_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.FLEX_START
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(150)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexEnd_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.FLEX_END
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_END))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(170)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(220)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(220)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(320)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_center_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.CENTER
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.CENTER))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(85)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(235)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceAround_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.SPACE_AROUND
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_AROUND))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(28)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(78)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(242)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(292)))
    }


    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceEvenly_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.SPACE_EVENLY
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_EVENLY))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(43)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(93)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(228)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(278)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceBetween_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.justifyContent = JustifyContent.SPACE_BETWEEN
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(320)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexStart_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.FLEX_START
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(320)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(220)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(170)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(220)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexEnd_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.FLEX_END
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_END))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(150)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(50)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_center_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.CENTER
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.CENTER))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(235)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(85)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(135)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceAround_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_AROUND
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_AROUND))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(242)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(292)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(28)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(78)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceEvenly_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_EVENLY
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_EVENLY))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(228)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(278)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(43)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(93)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceBetween_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 50, 100)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_BETWEEN
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.left, isEqualAllowingError(activity.dpToPixel(270)))
        assertThat(view0.right, isEqualAllowingError(activity.dpToPixel(320)))
        assertThat(view1.left, isEqualAllowingError(activity.dpToPixel(135)))
        assertThat(view1.right, isEqualAllowingError(activity.dpToPixel(185)))
        assertThat(view2.left, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view2.right, isEqualAllowingError(activity.dpToPixel(50)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexStart_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.FLEX_START
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(150)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexEnd_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.FLEX_END
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_END))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(90)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(140)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(140)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(240)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_center_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.CENTER
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.CENTER))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(45)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(195)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceAround_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.SPACE_AROUND
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_AROUND))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(15)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(65)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(175)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(225)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceEvenly_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.SPACE_EVENLY
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_EVENLY))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(23)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(73)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(167)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(217)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceBetween_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.justifyContent = JustifyContent.SPACE_BETWEEN
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(240)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexStart_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.FLEX_START
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(240)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(140)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(90)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(140)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_flexEnd_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.FLEX_END
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.FLEX_END))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(150)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(50)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_center_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.CENTER
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.CENTER))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(195)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(45)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(95)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceAround_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_AROUND
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_AROUND))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(175)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(225)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(15)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(65)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceEvenly_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_EVENLY
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_EVENLY))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(167)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(217)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(23)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(73)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testJustifyContent_spaceBetween_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 50)
            adapter.addItem(lp3)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            layoutManager.justifyContent = JustifyContent.SPACE_BETWEEN
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        assertThat(layoutManager.justifyContent, `is`(JustifyContent.SPACE_BETWEEN))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        val view0 = layoutManager.getChildAt(0)!!
        val view1 = layoutManager.getChildAt(1)!!
        val view2 = layoutManager.getChildAt(2)!!
        assertThat(view0.top, isEqualAllowingError(activity.dpToPixel(190)))
        assertThat(view0.bottom, isEqualAllowingError(activity.dpToPixel(240)))
        assertThat(view1.top, isEqualAllowingError(activity.dpToPixel(95)))
        assertThat(view1.bottom, isEqualAllowingError(activity.dpToPixel(145)))
        assertThat(view2.top, isEqualAllowingError(activity.dpToPixel(0)))
        assertThat(view2.bottom, isEqualAllowingError(activity.dpToPixel(50)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testLargeItem_scrollFast_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..199) {
                val lp = createLayoutParams(activity, 100, 50)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // Should be scrolled to the bottom by now
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        // Should be scrolled to the top
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testLargeItem_scrollFast_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..199) {
                val lp = createLayoutParams(activity, 70, 80)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))

        // Should be scrolled to the right edge by now
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        // Should be scrolled to the left edge by now
        assertThat(layoutManager.flexItemCount, `is`(200))
        // Only the visible items
        assertThat(layoutManager.childCount, `is`(not(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAlignItems_stretch_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 70, 80)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 70, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 70, 30)
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.alignItems, `is`(AlignItems.STRETCH))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        // Verify all items heights are stretched
        assertThat(layoutManager.getChildAt(0)!!.height, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(1)!!.height, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(2)!!.height, isEqualAllowingError(activity.dpToPixel(80)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAlignItems_stretch_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 80, 70)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 70)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 30, 70)
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.alignItems, `is`(AlignItems.STRETCH))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        // Verify all items widths are stretched
        assertThat(layoutManager.getChildAt(0)!!.width, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(1)!!.width, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(2)!!.width, isEqualAllowingError(activity.dpToPixel(80)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAlignSelf_stretch_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.FLEX_START
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 70, 80)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 70, 50)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 70, 30)
            lp3.alignSelf = AlignSelf.STRETCH
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.alignItems, `is`(AlignItems.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        // Verify the item whose align self is set to stretch is stretched
        assertThat(layoutManager.getChildAt(0)!!.height, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(1)!!.height, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(layoutManager.getChildAt(2)!!.height, isEqualAllowingError(activity.dpToPixel(80)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testAlignSelf_stretch_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.alignItems = AlignItems.FLEX_START
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 80, 70)
            adapter.addItem(lp1)
            val lp2 = createLayoutParams(activity, 50, 70)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 30, 70)
            lp3.alignSelf = AlignSelf.STRETCH
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.alignItems, `is`(AlignItems.FLEX_START))
        assertThat(layoutManager.flexItemCount, `is`(3))
        assertThat(layoutManager.flexLines.size, `is`(1))
        // Verify the item whose align self is set to stretch is stretched
        assertThat(layoutManager.getChildAt(0)!!.width, isEqualAllowingError(activity.dpToPixel(80)))
        assertThat(layoutManager.getChildAt(1)!!.width, isEqualAllowingError(activity.dpToPixel(50)))
        assertThat(layoutManager.getChildAt(2)!!.width, isEqualAllowingError(activity.dpToPixel(80)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testStretchViews_from_middle_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 70, 80)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.alignItems, `is`(AlignItems.STRETCH))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        activityRule.runOnUiThread {
            layoutManager.alignItems = AlignItems.STRETCH
            val lp = createLayoutParams(activity, 70, 20)
            // Add an item whose height is less than the other items.
            // But with alignItems set to stretch, the height of the item should be stretched
            adapter.addItem(lp)
            adapter.notifyDataSetChanged()
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.getChildAt(layoutManager.childCount - 1)!!.height,
                isEqualAllowingError(activity.dpToPixel(80)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testStretchViews_from_middle_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 70, 50)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.alignItems, `is`(AlignItems.STRETCH))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_RIGHT,
                GeneralLocation.TOP_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_RIGHT,
                GeneralLocation.TOP_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_RIGHT,
                GeneralLocation.TOP_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_RIGHT,
                GeneralLocation.TOP_LEFT))
        activityRule.runOnUiThread {
            layoutManager.alignItems = AlignItems.STRETCH
            val lp = createLayoutParams(activity, 20, 50)
            // Add an item whose width is less than the other items.
            // But with alignItems set to stretch, the width of the item should be stretched
            adapter.addItem(lp)
            adapter.notifyDataSetChanged()
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.getChildAt(layoutManager.childCount - 1)!!.width,
                isEqualAllowingError(activity.dpToPixel(70)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToTop_middleItem_as_anchorPosition() {
        // There was an issue that the anchor position was based on the first item in the first
        // visible flex line when scrolling to top. But the anchor position should be based on the
        // flex line position (view which has the minimum top position in the same flex line)
        // This test verifies the issue is fixed.
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val positionInSecondLine = 6
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.FLEX_START
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                var lp = createLayoutParams(activity, 70, 80)
                if (i == positionInSecondLine) {
                    // Change the height from other items in the second line, not the first item
                    // in the second line
                    lp = createLayoutParams(activity, 70, 130)
                }
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Each line has 4 (320 / 70) flex items and 12 (50 / 4) lines in total
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // By this moment reached to the bottom

        // Now scrolling to the top to see if the views in the first flex line is correctly placed
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))

        assertThat(layoutManager.getChildAt(positionInSecondLine)!!.bottom,
                isEqualAllowingError(activity.dpToPixel(210))) // 80 + 130
        // Verify that the view in the same line's cross axis position is correct
        assertThat(layoutManager.getChildAt(positionInSecondLine - 1)!!.bottom,
                isEqualAllowingError(activity.dpToPixel(160))) // 80 + 80
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToLeft_middleItem_as_anchorPosition() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val positionInSecondLine = 6
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.alignItems = AlignItems.FLEX_START
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                var lp = createLayoutParams(activity, 80, 50)
                if (i == positionInSecondLine) {
                    // Change the width from other items in the second line, not the first item
                    // in the second line
                    lp = createLayoutParams(activity, 130, 50)
                }
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Each line has 4 (240 / 50) flex items and 12 (50 / 4) lines in total
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        // By this moment reached to the right edge

        // Now scrolling to the left to see if the views in the first flex line is correctly placed
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))

        assertThat(layoutManager.getChildAt(positionInSecondLine)!!.right,
                isEqualAllowingError(activity.dpToPixel(210))) // 80 + 130
        // Verify that the view in the same line's cross axis position is correct
        assertThat(layoutManager.getChildAt(positionInSecondLine - 1)!!.right,
                isEqualAllowingError(activity.dpToPixel(160))) // 80 + 80
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToBottom_middleItem_as_anchorPosition() {
        // There was an issue that the anchor position was based on the last item in the last
        // visible flex line when scrolling to bottom. But the anchor position should be based on
        // the flex line position (view which has the maximum bottom position in the same flex line)
        // This test verifies the issue is fixed.
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val positionInSecondBottomLine = 45
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                var lp = createLayoutParams(activity, 70, 80)
                if (i == positionInSecondBottomLine) {
                    // Change the height from other items in the second bottom line
                    lp = createLayoutParams(activity, 70, 130)
                }
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Each line has 4 (320 / 70) flex items and 12 (50 / 4) lines in total
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // By this moment reached to the bottom

        // 4 comes from the number of flex items - positionInSecondBottomLine
        val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
        val anchorView = layoutManager.getChildAt(layoutManager.childCount - 4)
        assertThat(recyclerView.bottom - anchorView!!.top,
                isEqualAllowingError(activity.dpToPixel(210))) // 80 + 130
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToTop_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 70, 80)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Each line has 4 (320 / 70) flex items and 12 (50 / 4) lines in total
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // By this moment reached to the bottom

        // Now scrolling to the top to see if the views in the first flex line is correctly placed
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))

        assertThat((layoutManager.getChildAt(0) as TextView).text.toString(), `is`("1"))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFlexGrow_only_oneItem_has_positive_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..3) {
                val lp = createLayoutParams(activity, 100, 80)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 1 item
            // Give the second item in the first line a positive flex grow
            adapter.getItemAt(0).setHeight(activity.dpToPixel(140))
            adapter.getItemAt(1).flexGrow = 1.0f
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        // Verify the vertical position (cross size) of the second line is correctly positioned
        assertThat(layoutManager.getChildAt(3)!!.top, isEqualAllowingError(activity.dpToPixel(140)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFlexGrow_only_oneItem_has_positive_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..3) {
                val lp = createLayoutParams(activity, 70, 70)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 1 item
            // Give the second item in the first line a positive flex grow
            adapter.getItemAt(0).setWidth(activity.dpToPixel(120))
            adapter.getItemAt(1).flexGrow = 1.0f
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        // Verify the horizontal position (cross size) of the second line is correctly positioned
        assertThat(layoutManager.getChildAt(3)!!.left, isEqualAllowingError(activity.dpToPixel(120)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFirstReferenceView_middleOf_line_used_as_anchor() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.FLEX_END
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp1 = createLayoutParams(activity, 100, 80)
            adapter.addItem(lp1)
            // The second view in the first line has the maximum height in the same line
            val lp2 = createLayoutParams(activity, 100, 180)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 80)
            adapter.addItem(lp3)
            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 80)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // By this moment reached to the bottom

        // Now scrolling to the top to see if the views in the first flex line is correctly placed
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        // The top coordinate of the first view should be the height of the second view minus the
        // height of the first view (180 - 80)
        assertThat(layoutManager.getChildAt(0)!!.top, isEqualAllowingError(activity.dpToPixel(100)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testLastReferenceView_middleOf_line_used_as_anchor() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.FLEX_START
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 80)
                adapter.addItem(lp)
            }
            val lp1 = createLayoutParams(activity, 100, 80)
            adapter.addItem(lp1)
            // The second view in the last line has the maximum height in the same line
            val lp2 = createLayoutParams(activity, 100, 180)
            adapter.addItem(lp2)
            val lp3 = createLayoutParams(activity, 100, 80)
            adapter.addItem(lp3)
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // By this moment reached to the bottom

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        // The bottom coordinate of the first view in the last line should be the height of the
        // second view in the last line minus the height of the first view in the last line
        // (180 - 80)
        assertThat(layoutManager.getChildAt(layoutManager.childCount - 2)!!.bottom
                - layoutManager.getChildAt(layoutManager.childCount - 3)!!.bottom,
                isEqualAllowingError(activity.dpToPixel(100)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testRotateScreen_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 100)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.CENTER))

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        val anchorView = layoutManager.getChildAt(0)
        val offset = anchorView!!.top
        assertTrue(offset < 0)

        activityRule.runOnUiThread {
            val orientation = activity.resources.configuration.orientation
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            } else {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Verify that offset position is preserved for the first visible view after the rotation
        val anchorAfterRotate = layoutManager.getChildAt(0)
        assertTrue(anchorAfterRotate!!.top < 0)
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testRotateScreen_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.alignItems = AlignItems.STRETCH
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 100)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER))

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        val anchorView = layoutManager.getChildAt(0)
        val offset = anchorView!!.left
        assertTrue(offset < 0)

        activityRule.runOnUiThread {
            val orientation = activity.resources.configuration.orientation
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            } else {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Verify that offset position is preserved for the first visible view after the rotation
        val anchorAfterRotate = layoutManager.getChildAt(0)
        assertTrue(anchorAfterRotate!!.left < 0)
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDecoration_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val drawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        val itemDecoration = FlexboxItemDecoration(activity)
        itemDecoration.setDrawable(drawable)

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.addItemDecoration(itemDecoration)
            recyclerView.adapter = adapter

            for (i in 0..9) {
                val lp = createLayoutParams(activity, 90, 100)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        var view2 = layoutManager.getChildAt(1)
        // 90 (view width) + 10 (divider width)
        assertThat(view2!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        var view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 10 (divider width) + 90(view width) + 10 (divider width)
        assertThat(view3!!.left, isEqualAllowingError(activity.dpToPixel(200)))
        var view4 = layoutManager.getChildAt(3)
        // 100 (view height) + 15 (divider height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(115)))
        var view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 15 (divider height) + 100 (view height) + 15 (divider height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(230)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(HORIZONTAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view2 = layoutManager.getChildAt(1)
        // 90 (view width)
        assertThat(view2!!.left, isEqualAllowingError(activity.dpToPixel(90)))
        view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 90(view width)
        assertThat(view3!!.left, isEqualAllowingError(activity.dpToPixel(180)))
        view4 = layoutManager.getChildAt(3)
        // 100 (view height) + 15 (divider height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(115)))
        view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 15 (divider height) + 100 (view height) + 15 (divider height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(230)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(VERTICAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view2 = layoutManager.getChildAt(1)
        // 90 (view width) + 10 (divider width)
        assertThat(view2!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 10 (divider width) + 90(view width) + 10 (divider width)
        assertThat(view3!!.left, isEqualAllowingError(activity.dpToPixel(200)))
        view4 = layoutManager.getChildAt(3)
        // 100 (view height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(100)))
        view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 100 (view height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDecoration_direction_rowReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val drawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        val itemDecoration = FlexboxItemDecoration(activity)
        itemDecoration.setDrawable(drawable)

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW_REVERSE
            recyclerView.layoutManager = layoutManager
            recyclerView.addItemDecoration(itemDecoration)
            recyclerView.adapter = adapter

            for (i in 0..9) {
                val lp = createLayoutParams(activity, 90, 100)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW_REVERSE))
        var view1 = layoutManager.getChildAt(0)
        var view2 = layoutManager.getChildAt(1)
        // 90 (view width) + 10 (divider width)
        assertThat(view1!!.right - view2!!.right, isEqualAllowingError(activity.dpToPixel(100)))
        var view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 10 (divider width) + 90(view width) + 10 (divider width)
        assertThat(view1.right - view3!!.right, isEqualAllowingError(activity.dpToPixel(200)))
        var view4 = layoutManager.getChildAt(3)
        // 100 (view height) + 15 (divider height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(115)))
        var view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 15 (divider height) + 100 (view height) + 15 (divider height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(230)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(HORIZONTAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view1 = layoutManager.getChildAt(0)
        view2 = layoutManager.getChildAt(1)
        // 90 (view width)
        assertThat(view1!!.right - view2!!.right, isEqualAllowingError(activity.dpToPixel(90)))
        view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 90(view width)
        assertThat(view1.right - view3!!.right, isEqualAllowingError(activity.dpToPixel(180)))
        view4 = layoutManager.getChildAt(3)
        // 100 (view height) + 15 (divider height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(115)))
        view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 15 (divider height) + 100 (view height) + 15 (divider height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(230)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(VERTICAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view1 = layoutManager.getChildAt(0)
        view2 = layoutManager.getChildAt(1)
        // 90 (view width) + 10 (divider width)
        assertThat(view1!!.right - view2!!.right,
                isEqualAllowingError(activity.dpToPixel(100)))
        view3 = layoutManager.getChildAt(2)
        // 90 (view width) + 10 (divider width) + 90(view width) + 10 (divider width)
        assertThat(view1.right - view3!!.right,
                isEqualAllowingError(activity.dpToPixel(200)))
        view4 = layoutManager.getChildAt(3)
        // 100 (view height)
        assertThat(view4!!.top, isEqualAllowingError(activity.dpToPixel(100)))
        view7 = layoutManager.getChildAt(6)
        // 100 (view height) + 100 (view height)
        assertThat(view7!!.top, isEqualAllowingError(activity.dpToPixel(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDecoration_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val drawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        val itemDecoration = FlexboxItemDecoration(activity)
        itemDecoration.setDrawable(drawable)

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.addItemDecoration(itemDecoration)
            recyclerView.adapter = adapter

            for (i in 0..9) {
                val lp = createLayoutParams(activity, 90, 65)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        var view2 = layoutManager.getChildAt(1)
        // 65 (view height) + 15 (divider height)
        assertThat(view2!!.top, isEqualAllowingError(activity.dpToPixel(80)))
        var view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 15 (divider height) + 65 (view height) + 15 (divider height)
        assertThat(view3!!.top, isEqualAllowingError(activity.dpToPixel(160)))
        var view4 = layoutManager.getChildAt(3)
        // 90 (view width) + 10 (divider width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        var view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 10 (divider width) + 90 (view width) + 10 (divider width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(200)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(HORIZONTAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view2 = layoutManager.getChildAt(1)
        // 65 (view height) + 15 (divider height)
        assertThat(view2!!.top, isEqualAllowingError(activity.dpToPixel(80)))
        view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 15 (divider height) + 65 (view height) + 15 (divider height)
        assertThat(view3!!.top, isEqualAllowingError(activity.dpToPixel(160)))
        view4 = layoutManager.getChildAt(3)
        // 90 (view width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(90)))
        view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 90 (view width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(180)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(VERTICAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view2 = layoutManager.getChildAt(1)
        // 65 (view height)
        assertThat(view2!!.top, isEqualAllowingError(activity.dpToPixel(65)))
        view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 65 (view height)
        assertThat(view3!!.top, isEqualAllowingError(activity.dpToPixel(130)))
        view4 = layoutManager.getChildAt(3)
        // 90 (view width) + 10 (divider width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 10 (divider width) + 90 (view width) + 10 (divider width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDecoration_direction_columnReverse() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val drawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        val itemDecoration = FlexboxItemDecoration(activity)
        itemDecoration.setDrawable(drawable)

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN_REVERSE
            recyclerView.layoutManager = layoutManager
            recyclerView.addItemDecoration(itemDecoration)
            recyclerView.adapter = adapter

            for (i in 0..9) {
                val lp = createLayoutParams(activity, 90, 65)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN_REVERSE))
        var view1 = layoutManager.getChildAt(0)
        var view2 = layoutManager.getChildAt(1)
        // 65 (view height) + 15 (divider height)
        assertThat(view1!!.top - view2!!.top, isEqualAllowingError(activity.dpToPixel(80)))
        var view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 15 (divider height) + 65 (view height) + 15 (divider height)
        assertThat(view1.top - view3!!.top, isEqualAllowingError(activity.dpToPixel(160)))
        var view4 = layoutManager.getChildAt(3)
        // 90 (view width) + 10 (divider width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        var view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 10 (divider width) + 90 (view width) + 10 (divider width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(200)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(HORIZONTAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view1 = layoutManager.getChildAt(0)
        view2 = layoutManager.getChildAt(1)
        // 65 (view height) + 15 (divider height)
        assertThat(view1!!.top - view2!!.top, isEqualAllowingError(activity.dpToPixel(80)))
        view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 15 (divider height) + 65 (view height) + 15 (divider height)
        assertThat(view1.top - view3!!.top, isEqualAllowingError(activity.dpToPixel(160)))
        view4 = layoutManager.getChildAt(3)
        // 90 (view width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(90)))
        view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 90 (view width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(180)))

        activityRule.runOnUiThread {
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.removeItemDecoration(itemDecoration)
            itemDecoration.setOrientation(VERTICAL)
            recyclerView.addItemDecoration(itemDecoration)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        view1 = layoutManager.getChildAt(0)
        view2 = layoutManager.getChildAt(1)
        // 65 (view height)
        assertThat(view1!!.top - view2!!.top, isEqualAllowingError(activity.dpToPixel(65)))
        view3 = layoutManager.getChildAt(2)
        // 65 (view height) + 65 (view height)
        assertThat(view1.top - view3!!.top, isEqualAllowingError(activity.dpToPixel(130)))
        view4 = layoutManager.getChildAt(3)
        // 90 (view width) + 10 (divider width)
        assertThat(view4!!.left, isEqualAllowingError(activity.dpToPixel(100)))
        view7 = layoutManager.getChildAt(6)
        // 90 (view width) + 10 (divider width) + 90 (view width) + 10 (divider width)
        assertThat(view7!!.left, isEqualAllowingError(activity.dpToPixel(200)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToPosition_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..149) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 3 items
            // ....
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        val scrollTo = 42
        activityRule.runOnUiThread { layoutManager.scrollToPosition(scrollTo) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Each flex line should have 3 items in this test's configuration.
        // After scrolling to the position of 42 (% 3 == 0), the first visible item should
        // be the 42'th item
        assertThat((layoutManager.getChildAt(0) as TextView).text.toString(),
                `is`((scrollTo + 1).toString()))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // Scroll enough that 42'th item becomes off screen to the top

        activityRule.runOnUiThread { layoutManager.scrollToPosition(scrollTo) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // The 42'th item should be at the bottom of the screen.
        // The last visible item should be 42 + 3 since the last visible item is at the last
        // of the bottom flex line
        assertThat((layoutManager.getChildAt(layoutManager.childCount - 1) as TextView).text.toString(),
                `is`((scrollTo + 3).toString()))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToPosition_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..149) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 3 items
            // ....
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))

        val scrollTo = 42
        activityRule.runOnUiThread { layoutManager.scrollToPosition(scrollTo) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Each flex line should have 3 items in this test's configuration.
        // After scrolling to the position of 42 (% 3 == 0), the first visible item should
        // be the 42'th item
        assertThat((layoutManager.getChildAt(0) as TextView).text.toString(),
                `is`((scrollTo + 1).toString()))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        // Scroll enough that 42'th item becomes off screen to the left

        activityRule.runOnUiThread { layoutManager.scrollToPosition(scrollTo) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // The 42'th item should be at the bottom of the screen.
        // The last item should be the (42 + 3)'th item since it should be also the last item in the
        // bottom flex line
        assertThat((layoutManager.getChildAt(layoutManager.childCount - 1) as TextView).text.toString(),
                `is`((scrollTo + 3).toString()))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToPosition_scrollToNewItem_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..5) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // There should be 2 lines
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 3 items
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        activityRule.runOnUiThread {
            val lp = createLayoutParams(activity, 100, 70)
            adapter.addItem(lp)
            layoutManager.scrollToPosition(adapter.itemCount - 1)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // ChildCount (visible views) should be 6 + 1,
        // which before fixing https://github.com/google/flexbox-layout/issues/206, only the new
        // item was visible
        assertThat(layoutManager.childCount, `is`(7))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToPosition_scrollToNewItem_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..5) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // There should be 2 lines
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 3 items
            // Flex line 2: 3 items
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))

        activityRule.runOnUiThread {
            val lp = createLayoutParams(activity, 100, 70)
            adapter.addItem(lp)
            layoutManager.scrollToPosition(adapter.itemCount - 1)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // ChildCount (visible views) should be 6 + 1,
        // which before fixing https://github.com/google/flexbox-layout/issues/206, only the new
        // item was visible
        assertThat(layoutManager.childCount, `is`(7))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollToStart_secondLineHasMoreItemThanFirst() {
        // This test verifies the case that the first line disappears as the user first scrolls to
        // the bottom enough that the first line becomes invisible then the user scrolls toward
        // start on the condition that the second line has more items than the first line
        // https://github.com/google/flexbox-layout/issues/228

        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()

        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val first = FlexboxLayoutManager.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, activity.dpToPixel(70))
            adapter.addItem(first)
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // The first line has 1 item, the following lines have more than 1 items
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 1 items
            // Flex line 2: 3 items
            // Flex line 3: 3 items
            // ...
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        // At this moment, the first item should become invisible
        var firstView = layoutManager.getChildAt(0)
        assertThat((firstView as TextView).text.toString(), `is`(not("1")))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))

        // The first visible item should be "1", which before fixing the issue
        // https://github.com/google/flexbox-layout/issues/228, the first line disappeared.
        firstView = layoutManager.getChildAt(0)
        assertThat((firstView as TextView).text.toString(), `is`("1"))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testNestedRecyclerViews_direction_row() {
        // This test verifies the nested RecyclerViews.
        // The outer RecyclerView scrolls vertical using LinearLayoutManager.
        // The inner RecyclerViews use FlexboxLayoutManager with flexDirection == ROW and
        // height of the RecyclerView is set to "wrap_content", which before fixing
        // https://github.com/google/flexbox-layout/issues/208, the height of the inner
        // RecyclerViews were set to 0.
        val activity = activityRule.activity
        val outerLayoutManager = LinearLayoutManager(activity)

        // Give the inner adapter item count enough so that inner RecyclerView with
        // FlexboxLayoutManager wraps its items
        val innerAdapterItemCount = 20
        val adapter = NestedOuterAdapter(FlexDirection.ROW,
                innerAdapterItemCount, R.layout.viewholder_inner_recyclerview)
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            outerLayoutManager.orientation = LinearLayoutManager.VERTICAL
            recyclerView.layoutManager = outerLayoutManager
            recyclerView.adapter = adapter
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val viewHolder = adapter.getViewHolder(0)
        val innerRecyclerView = viewHolder.innerRecyclerView
        assertThat(innerRecyclerView.height, `is`(not(0)))

        // This assertion verifies that inner RecyclerView displays the entire items including
        // wrapped lines to verify the issue that nested RecyclerView with FlexboxLayoutManager
        // only displayed one line https://github.com/google/flexbox-layout/issues/290
        assertThat((innerRecyclerView.layoutManager as FlexboxLayoutManager).findLastVisibleItemPosition(),
                `is`(innerAdapterItemCount - 1))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testNestedRecyclerViews_direction_column() {
        // This test verifies the nested RecyclerViews.
        // The outer RecyclerView scrolls horizontally using LinearLayoutManager.
        // The inner RecyclerViews use FlexboxLayoutManager with flexDirection == COLUMN and
        // width of the RecyclerView is set to "wrap_content", which before fixing
        // https://github.com/google/flexbox-layout/issues/208, the width of the inner
        // RecyclerViews were set to 0.
        val activity = activityRule.activity
        val outerLayoutManager = androidx.recyclerview.widget.LinearLayoutManager(activity)

        // Give the inner adapter item count enough so that inner RecyclerView with
        // FlexboxLayoutManager wraps its items
        val innerAdapterItemCount = 20
        val adapter = NestedOuterAdapter(FlexDirection.COLUMN,
                innerAdapterItemCount, R.layout.viewholder_inner_recyclerview_wrap_horizontally)
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            outerLayoutManager.orientation = androidx.recyclerview.widget.LinearLayoutManager.HORIZONTAL
            recyclerView.layoutManager = outerLayoutManager
            recyclerView.adapter = adapter
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val viewHolder = adapter.getViewHolder(0)
        val innerRecyclerView = viewHolder.innerRecyclerView
        assertThat(innerRecyclerView.width, `is`(not(0)))

        // This assertion verifies that inner RecyclerView displays the entire items including
        // wrapped lines to verify the issue that nested RecyclerView with FlexboxLayoutManager
        // only displayed one line https://github.com/google/flexbox-layout/issues/290
        assertThat((innerRecyclerView.layoutManager as FlexboxLayoutManager).findLastVisibleItemPosition(),
                `is`(innerAdapterItemCount - 1))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFindVisibleChild_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 75)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // At first three completely visible lines.
            // Flex line 1, item count 3 (0, 1, 2)
            // Flex line 2, item count 3 (3, 4, 5)
            // Flex line 3, item count 3 (6, 7, 8)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.findFirstCompletelyVisibleItemPosition(), `is`(0))
        assertThat(layoutManager.findFirstVisibleItemPosition(), `is`(0))
        assertThat(layoutManager.findLastCompletelyVisibleItemPosition(), `is`(8))
        assertThat(layoutManager.findLastVisibleItemPosition(), `is`(11))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.findFirstCompletelyVisibleItemPosition(), `is`(42))
        assertThat(layoutManager.findFirstVisibleItemPosition(), `is`(39))
        assertThat(layoutManager.findLastCompletelyVisibleItemPosition(), `is`(49))
        assertThat(layoutManager.findLastVisibleItemPosition(), `is`(49))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testFindVisibleChild_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 75)
                adapter.addItem(lp)
            }
            // RecyclerView width: 320, height: 240.
            // At first three completely visible lines.
            // Flex line 1, item count 3 (0, 1, 2)
            // Flex line 2, item count 3 (3, 4, 5)
            // Flex line 3, item count 3 (6, 7, 8)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.findFirstCompletelyVisibleItemPosition(), `is`(0))
        assertThat(layoutManager.findFirstVisibleItemPosition(), `is`(0))
        assertThat(layoutManager.findLastCompletelyVisibleItemPosition(), `is`(8))
        assertThat(layoutManager.findLastVisibleItemPosition(), `is`(11))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(layoutManager.findFirstCompletelyVisibleItemPosition(), `is`(42))
        assertThat(layoutManager.findFirstVisibleItemPosition(), `is`(39))
        assertThat(layoutManager.findLastCompletelyVisibleItemPosition(), `is`(49))
        assertThat(layoutManager.findLastVisibleItemPosition(), `is`(49))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDrawDirtyFlexLine_direction_row() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 75)
                adapter.addItem(lp)
            }
        }
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // First scroll to the bottom, then add a new item that isn't visible at this moment.
        activityRule.runOnUiThread {
            val lp = createLayoutParams(activity, 40, 75)
            adapter.addItem(0, lp)
        }
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        val firstVisible = layoutManager.getChildAt(0)
        assertThat(firstVisible!!.width, isEqualAllowingError(activity.dpToPixel(40)))
        assertThat(firstVisible.height, isEqualAllowingError(activity.dpToPixel(75)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDrawDirtyFlexLine_direction_column() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter

            for (i in 0..29) {
                val lp = createLayoutParams(activity, 100, 75)
                adapter.addItem(lp)
            }
        }
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // First scroll to the bottom, then add a new item that isn't visible at this moment.
        activityRule.runOnUiThread {
            val lp = createLayoutParams(activity, 100, 120)
            adapter.addItem(0, lp)
        }
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        val firstVisible = layoutManager.getChildAt(0)
        assertThat(firstVisible!!.width, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(firstVisible.height, isEqualAllowingError(activity.dpToPixel(120)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testDrawDirtyFlexLine_multi_viewTypes_direction_row() {
        // This test verifies https://github.com/google/flexbox-layout/issues/280
        // the position of the view type is shifted if a new item is inserted before the
        // view which has the special viewType and that view isn't visible at the time the item
        // was inserted.
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapterMultiViewTypes()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val parent = activity.findViewById<RecyclerView>(R.id.recyclerview)
        var matchParentText = layoutManager
                .getChildAt(TestAdapterMultiViewTypes.POSITION_MATCH_PARENT) as TextView
        assertThat(matchParentText.width, `is`(parent.width))
        assertThat(matchParentText.text.toString(),
                `is`<String>((TestAdapterMultiViewTypes.POSITION_MATCH_PARENT + 1).toString()))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))

        val insertedValue = 10
        activityRule.runOnUiThread {
            val item = TestAdapterMultiViewTypes.Item()
            item.value = insertedValue
            // Insert an item before the position that has a special viewType
            adapter.addItemAt(TestAdapterMultiViewTypes.POSITION_MATCH_PARENT - 1, item)
        }
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        // Since a new item is inserted before the position, the index at the view who has the
        // special viewType should be shifted.
        matchParentText = layoutManager
                .getChildAt(TestAdapterMultiViewTypes.POSITION_MATCH_PARENT + 1) as TextView
        assertThat(matchParentText.width, `is`(parent.width))
        assertThat(matchParentText.text.toString(),
                `is`<String>((TestAdapterMultiViewTypes.POSITION_MATCH_PARENT + 1).toString()))

        // The position of this view is the old position who had the special viewType, but
        // now the viewType should be a normal one
        val textView = layoutManager
                .getChildAt(TestAdapterMultiViewTypes.POSITION_MATCH_PARENT - 1) as TextView
        assertThat(textView.width, lessThan(parent.width))
        assertThat(textView.text.toString(), `is`(insertedValue.toString()))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testChildrenSizeWithMargin() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp = createLayoutParams(activity, 100, 30)
            lp.setMargins(10, 30, 20, 40)
            adapter.addItem(lp)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val text = layoutManager.getChildAt(0) as TextView
        val lp = text.layoutParams as FlexboxLayoutManager.LayoutParams
        assertThat(text.height, isEqualAllowingError(activity.dpToPixel(30)))
        assertThat(text.width, isEqualAllowingError(activity.dpToPixel(100)))
        assertThat(lp.marginLeft, isEqualAllowingError(10))
        assertThat(lp.marginRight, isEqualAllowingError(20))
        assertThat(lp.marginTop, isEqualAllowingError(30))
        assertThat(lp.marginBottom, isEqualAllowingError(40))
        activityRule.runOnUiThread { layoutManager.flexDirection = FlexDirection.COLUMN }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val text2 = layoutManager.getChildAt(0) as TextView
        assertThat(text2.height, isEqualAllowingError(activity.dpToPixel(30)))
        assertThat(text2.width, isEqualAllowingError(activity.dpToPixel(100)))

    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testItemDecoration_withScrolling_direction_row() {
        // This test verifies the case that the item decoration set through FlexboxItemDecoration
        // is misplaced after the user scrolls the RecyclerView
        // https://github.com/google/flexbox-layout/issues/285

        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val decorationDrawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val decoration = FlexboxItemDecoration(activity)
            decoration.setDrawable(decorationDrawable)
            recyclerView.addItemDecoration(decoration)
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // The first line has 1 item, the following lines have more than 1 items
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 1 items
            // Flex line 2: 3 items
            // Flex line 3: 3 items
            // ...
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.ROW))
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(0)!!), `is`(0))
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(1)!!), `is`(0))
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(2)!!), `is`(0))
        layoutManager.flexLines
                .mapNotNull { layoutManager.getChildAt(it.firstIndex) }
                .forEach { assertThat(layoutManager.getLeftDecorationWidth(it), `is`(0)) }

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))

        // Verify even after the scrolling, decoration values are set correctly
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(0)!!), `is`(0))
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(1)!!), `is`(0))
        assertThat(layoutManager.getTopDecorationHeight(layoutManager.getChildAt(2)!!), `is`(0))
        layoutManager.flexLines
                .mapNotNull { layoutManager.getChildAt(it.firstIndex) }
                .forEach { assertThat(layoutManager.getLeftDecorationWidth(it), `is`(0)) }
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testItemDecoration_withScrolling_direction_column() {
        // This test verifies the case that the item decoration set through FlexboxItemDecoration
        // is misplaced after the user scrolls the RecyclerView
        // https://github.com/google/flexbox-layout/issues/285

        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val decorationDrawable = ResourcesCompat.getDrawable(activity.resources, R.drawable.divider, null)
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val decoration = FlexboxItemDecoration(activity)
            decoration.setDrawable(decorationDrawable)
            recyclerView.addItemDecoration(decoration)
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
            // The first line has 1 item, the following lines have more than 1 items
            // RecyclerView width: 320, height: 240.
            // Flex line 1: 1 items
            // Flex line 2: 3 items
            // Flex line 3: 3 items
            // ...
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexDirection, `is`(FlexDirection.COLUMN))
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(0)!!), `is`(0))
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(1)!!), `is`(0))
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(2)!!), `is`(0))
        layoutManager.flexLines
                .mapNotNull { layoutManager.getChildAt(it.firstIndex) }
                .forEach { assertThat(layoutManager.getTopDecorationHeight(it), `is`(0)) }

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))

        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.recyclerview)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))

        // Verify even after the scrolling, decoration values are set correctly
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(0)!!), `is`(0))
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(1)!!), `is`(0))
        assertThat(layoutManager.getLeftDecorationWidth(layoutManager.getChildAt(2)!!), `is`(0))
        layoutManager.flexLines
                .mapNotNull { layoutManager.getChildAt(it.firstIndex) }
                .forEach { assertThat(layoutManager.getTopDecorationHeight(it), `is`(0)) }
    }


    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testNotifyItemChange_withPayload() {
        // This test verifies the payload is correctly passed to the Adapter in the case
        // that notifying an item with payload
        // https://github.com/google/flexbox-layout/issues/297

        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            val lp = createLayoutParams(activity, 100, 70)
            adapter.addItem(lp)
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(adapter.payloads.size, `is`(0))

        val payload = "payload"
        activityRule.runOnUiThread { adapter.changeItemWithPayload(0, payload) }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()

        assertThat(adapter.payloads.size, `is`(1))
        assertThat(adapter.payloads[0] as String, `is`(payload))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollAlongManAxis_direction_row() {
        // This test verifies the scroll along the main axis if the width of the RecyclerView is
        // larger than its parent when the main axis direction is horizontal (row)
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.wrapped_recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 100, 70)
                adapter.addItem(lp)
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val view = layoutManager.getChildAt(0)!!
        assertThat(view.left, `is`(0))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_RIGHT,
                GeneralLocation.CENTER_LEFT))
        assertThat(view.left, `is`(not(0)))

        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.CENTER_LEFT,
                GeneralLocation.CENTER_RIGHT))
        assertThat(view.left, `is`(0))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testScrollAlongManAxis_direction_column() {
        // This test verifies the scroll along the main axis if the height of the RecyclerView is
        // larger than its parent when the main axis direction is vertical (column).
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.wrapped_recyclerview_scroll_vertical)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 0..49) {
                val lp = createLayoutParams(activity, 70, 100)
                adapter.addItem(lp)
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val view = layoutManager.getChildAt(0)!!
        assertThat(view.top, `is`(0))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.BOTTOM_CENTER,
                GeneralLocation.TOP_CENTER))
        assertThat(view.top, `is`(not(0)))

        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        onView(withId(R.id.container)).perform(swipe(GeneralLocation.TOP_CENTER,
                GeneralLocation.BOTTOM_CENTER))
        assertThat(view.top, `is`(0))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testMaxLine() {
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.maxLine = 3
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 1..50) {
                val lp = createLayoutParams(activity, 100, 70)
                lp.flexShrink = 0f
                adapter.addItem(lp)
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        assertThat(layoutManager.flexLines.size, `is`(3))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testNowrap_justifyContentCenter_directionRow() {
        // This is to fix https://github.com/google/flexbox-layout/issues/469
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val height = 70
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.ROW
            layoutManager.flexWrap = FlexWrap.NOWRAP
            layoutManager.justifyContent = JustifyContent.CENTER
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 1..3) {
                val lp = createLayoutParams(activity, 100, height)
                adapter.addItem(lp)
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val view1Bottom= layoutManager.getChildAt(0)!!.bottom
        val view2Bottom = layoutManager.getChildAt(1)!!.bottom
        val view3Bottom = layoutManager.getChildAt(2)!!.bottom
        assertThat(view1Bottom, `is`(activity.dpToPixel(height)))
        assertThat(view2Bottom, `is`(activity.dpToPixel(height)))
        assertThat(view3Bottom, `is`(activity.dpToPixel(height)))
    }

    @Test
    @FlakyTest
    @Throws(Throwable::class)
    fun testNowrap_justifyContentCenter_directionColumn() {
        // This is to fix https://github.com/google/flexbox-layout/issues/469
        val activity = activityRule.activity
        val layoutManager = FlexboxLayoutManager(activity)
        val adapter = TestAdapter()
        val width = 100
        activityRule.runOnUiThread {
            activity.setContentView(R.layout.recyclerview)
            val recyclerView = activity.findViewById<RecyclerView>(R.id.recyclerview)
            layoutManager.flexDirection = FlexDirection.COLUMN
            layoutManager.flexWrap = FlexWrap.NOWRAP
            layoutManager.justifyContent = JustifyContent.CENTER
            recyclerView.layoutManager = layoutManager
            recyclerView.adapter = adapter
            for (i in 1..3) {
                val lp = createLayoutParams(activity, width, 70)
                adapter.addItem(lp)
            }
        }
        InstrumentationRegistry.getInstrumentation().waitForIdleSync()
        val view1Right= layoutManager.getChildAt(0)!!.right
        val view2Right = layoutManager.getChildAt(1)!!.right
        val view3Right = layoutManager.getChildAt(2)!!.right
        assertThat(view1Right, `is`(activity.dpToPixel(width)))
        assertThat(view2Right, `is`(activity.dpToPixel(width)))
        assertThat(view3Right, `is`(activity.dpToPixel(width)))
    }

    /**
     * Creates a new flex item.
     *
     * @param context the context
     * @param width   in DP
     * @param height  in DP
     * @return the created [FlexboxLayoutManager.LayoutParams] instance
     */
    private fun createLayoutParams(context: Context, width: Int,
                                   height: Int): FlexboxLayoutManager.LayoutParams {
        return FlexboxLayoutManager.LayoutParams(context.dpToPixel(width), context.dpToPixel(height))
    }

    private fun swipe(from: CoordinatesProvider, to: CoordinatesProvider): ViewAction {
        return GeneralSwipeAction(Swipe.FAST, from, to, Press.FINGER)
    }
}
